package kisti.module.log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Properties;

import kisti.module.Notification.Notification;

/**
 * <pre>
 * kisti.module.log
 *   |_ LogFileWriter.java
 * 
 * </pre>
 * 
 * Desc :
 * 
 * @Company : KISTI
 * @Author :daniel
 * @Date :2011. 11. 15. 오후 3:26:34
 * @Version:
 * 
 */
public class Glog {

	private static String linuxPath = "/var/log/";
	private static String windowsPath = "c:\\";
	private static String gMan_Log = "gMan_Log";
	private static String gMan_accessLog = "gMan_accessLog";
	public static int LOG_ERROR = 0;
	public static int LOG_COMMON = 1;
	public static int LOG_USERACCESS = 2;

	
	public Glog() {
		// TODO Auto-generated constructor stub
	}
	
	
	/**
	 * 
	 * Desc : 아카이빙로그파일 사전에 만들어 둔다. 서버 시작할때 호출한다. 
	 * @Method Name : initialize
	 *
	 */
	public static void initialize() {


		// 로그파일 미리 만들어 두기
		try {
			Runtime runtime = Runtime.getRuntime();

			if (getSystemInfo().contains("Linux")) {
				runtime.exec("touch /var/log/gMan_Log.log");
				runtime.exec("touch /var/log/gMan_Log1.log");
				runtime.exec("touch /var/log/gMan_Log2.log");

				runtime.exec("touch /var/log/gMan_accessLog.log");
				runtime.exec("touch /var/log/gMan_accessLog1.log");
				runtime.exec("touch /var/log/gMan_accessLog2.log");

			} else if (getSystemInfo().contains("Windows")) {
				new FileWriter("c:\\gMan_Log.log");
				new FileWriter("c:\\gMan_Log1.log");
				new FileWriter("c:\\gMan_Log2.log");
				
				new FileWriter("c:\\gMan_accessLog.log");
				new FileWriter("c:\\gMan_accessLog1.log");
				new FileWriter("c:\\gMan_accessLog2.log");
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * Desc : 서버가 실행되는 서버의 OS정보를 가져온다.
	 * 
	 * @Method Name : getSystemInfo
	 * @return 해당 OS정보 이름을 반환
	 * 
	 */
	private static String getSystemInfo() {
		Properties properties = System.getProperties();
		return properties.getProperty("os.name"); // return Linux, Windows 7
	}

	/**
	 * 
	 * Desc : 로그의 타입을 구분하여 타입에 따라 로그를 저장할 파일 경로를 생성한다.
	 * 
	 * @Method Name : getFilePath
	 * @param typeOfLog
	 * @return 로그파일을 쓸 파일 PATH를 반환
	 * 
	 */
	private static String getFilePath(int typeOfLog) {
		String logFilePath = "";

		if (getSystemInfo().contains("Linux")) {
			logFilePath = linuxPath;
		} else if (getSystemInfo().contains("Windows")) {
			logFilePath = windowsPath;
		}

		if (typeOfLog == LOG_ERROR || typeOfLog == LOG_COMMON) {
			logFilePath += gMan_Log;
		} else {
			logFilePath += gMan_accessLog;
		}

		return logFilePath;

	}

	/**
	 * 
	 * Desc :
	 * 
	 * @Method Name : checkLogFile
	 * @param filePath
	 * 
	 */
	private static void switchLogFile(String filePath) {

		File file = new File(filePath + ".log");

		try {
			if (getSystemInfo().contains("Linux")) {

				if (file.length() > 20000000) { // 20M 넘으면
					Runtime runtime = Runtime.getRuntime();

					if (filePath.contains("gMan_Log")) {
						// 응용프로그램의 서브 프로세스인 Process 객체를 얻는다.
						// Process process =
						runtime.exec("mv /var/log/gMan_Log2.log /var/log/gMan_Log_tmp.log");
						runtime.exec("mv /var/log/gMan_Log1.log /var/log/gMan_Log2.log");
						runtime.exec("mv /var/log/gMan_Log.log /var/log/gMan_Log1.log");
						runtime.exec("mv /var/log/gMan_Log_tmp.log /var/log/gMan_Log.log");

						// //응용 프로그램의 입력 스트림을 구한다.
						// BufferedReader br = new BufferedReader( new
						// InputStreamReader(process.getInputStream()) );
						//
						// //응용프로그램의 입력 스트림에서 한 라인씩 읽어서 응용 프로그램의 표준 출력으로 보낸다.
						// String result = "";
						// while ( (result = br.readLine()) != null ) {
						// System.out.println(result);
						// }
						// br.close();

					} else if (filePath.contains("gMan_accessLog")) {
						runtime.exec("mv /var/log/gMan_accessLog2.log /var/log/gMan_accessLog_tmp.log");
						runtime.exec("mv /var/log/gMan_accessLog1.log /var/log/gMan_accessLog2.log");
						runtime.exec("mv /var/log/gMan_accessLog.log /var/log/gMan_accessLog1.log");
						runtime.exec("mv /var/log/gMan_accessLog_tmp.log /var/log/gMan_accessLog.log");
					}

				}

			} else if (getSystemInfo().contains("Windows")) {
				if (file.length() > 20000000) { // 20M 넘으면
					Runtime runtime = Runtime.getRuntime();

					if (filePath.contains("gMan_Log")) {

						runtime.exec("copy c:\\gMan_Log2.log c:\\gMan_Log_tmp.log");
						runtime.exec("copy c:\\gMan_Log1.log c:\\gMan_Log2.log");
						runtime.exec("copy c:\\gMan_Log.log c:\\gMan_Log1.log");
						runtime.exec("copy c:\\gMan_Log_tmp.log c:\\gMan_Log.log");

					} else if (filePath.contains("gMan_accessLog")) {
						runtime.exec("copy c:\\gMan_accessLog2.log c:\\gMan_accessLog_tmp.log");
						runtime.exec("copy c:\\gMan_accessLog1.log c:\\gMan_accessLog2.log");
						runtime.exec("copy c:\\gMan_accessLog.log c:\\gMan_accessLog1.log");
						runtime.exec("copy c:\\gMan_accessLog_tmp.log c:\\gMan_accessLog.log");
					}
				}
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * Desc : 로그를 파일에 쓴다. Append 형식으로 파일 끝에 새로그를 추가한다.
	 * 
	 * @Method Name : writeLogToFile
	 * @param filePath
	 *            로그를 쓸 파일 경로
	 * @param logMessages
	 *            파일에 쓸 로그 메시지
	 * 
	 */
	private static void writeLogToFile(String filePath, String logMessages) {
		System.out.println("" + filePath);
		System.out.println("" + logMessages);

		switchLogFile(filePath);

		try {
			FileWriter fw = new FileWriter(filePath + ".log", true);
			fw.write(logMessages + "\n");
			fw.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}

	}

	/**
	 * 
	 * Desc : 로그에 사용할 현재 시각을 가져온다.
	 * 
	 * @Method Name : getCurrentTime
	 * @return 현재시각을 "yyy-MM-dd HH:mm:ss" 형식으로 반환
	 * 
	 */
	private static String getCurrentTime() {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currentTime = formatter.format(calendar.getTime());
		return currentTime;
	}

	/**
	 * 
	 * Desc : 로그 형식과, 메시지 , 메시지가 발생한 위치를 가지고 로그 타입을 구분하여 해당 로그 파일에 저장한다.
	 * 
	 * @Method Name : Log
	 * @param typeOfLog
	 *            로그타입 정보
	 * @param logLocation
	 *            로그가 발생한 위치정보
	 * @param message
	 *            로그 메시지
	 * 
	 */
	public static void Log(int typeOfLog, String logLocation, String message) {

		// type에 따른 file path 가져온다.
		String logFilePath = getFilePath(typeOfLog);
		String logMessage = "";

		if (typeOfLog == LOG_USERACCESS) {
			logMessage += getCurrentTime() + ": " + message;

		} else if (typeOfLog == LOG_COMMON || typeOfLog == LOG_ERROR) {

			if (typeOfLog == LOG_COMMON) {
				logMessage += getCurrentTime() + ":" + " [COMMON] ["
						+ logLocation + "] " + message;
			} else if (typeOfLog == LOG_ERROR) {
				logMessage += getCurrentTime() + ":" + " [ERROR] ["
						+ logLocation + "] " + message;
				
				
//				Notification nf = new Notification();
//				nf.sender_email(logMessage);
//				nf.sender_sms("G-man TierServer has a error Please check your e-mail");
				
			}
		}

		// 파일에 쓴다.
		writeLogToFile(logFilePath, logMessage);

	}

	/**
	 * Desc :
	 * 
	 * @Method Name : main
	 * @param args
	 * 
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		// System.out.println(getSystemInfo());
		// System.out.println(getCurrentTime());
		// Log.log(LOG_ERROR,"logTester", "this is messages from logTester");

	}
}
